#include <GL/glew.h>
#include "math_3d.h"
#ifndef AffineTransform_H
#define AffineTransform_H
struct CCAffineTransform {
	float a, b, c, d;
	float tx, ty;
	CCAffineTransform(){}
	CCAffineTransform(float a,float b,float c,float d,float tx,float ty):a(a),b(b),c(c),d(d),tx(tx),ty(ty){}
	void print()
	{
		printf("%f,%f,%f,%f,%f,%f\n",a,b,c,d,tx,ty);
	}
};
struct  CCPoint
{
	float x;
	float y;
	CCPoint(){}
	CCPoint(float x, float y):x(x),y(y){}
	bool CCPoint::equals(const CCPoint& target) const
	{
		return ((x == target.x) && (y == target.y));
	}
};
const CCPoint CCPointZero(0,0);
struct  CCSize
{
	float width;
	float height;
	CCSize(){}
	CCSize(float width, float height):width(width),height(height){}
};
const CCSize CCSizeZero = CCSize(0,0);
struct  CCRect
{
	CCPoint origin;
	CCSize  size;

	CCRect(float x, float y, float width, float height)
	{
		origin.x = x;
		origin.y = y;

		size.width = width;
		size.height = height;
	}
	float getMaxX() const
	{
		return (float)(origin.x + size.width);
	}

	float getMidX() const
	{
		return (float)(origin.x + size.width / 2.0);
	}

	float getMinX() const
	{
		return origin.x;
	}

	float getMaxY() const
	{
		return origin.y + size.height;
	}

	float getMidY() const
	{
		return (float)(origin.y + size.height / 2.0);
	}

	float getMinY() const
	{
		return origin.y;
	}
	bool containsPoint(const CCPoint& point) const
	{
		bool bRet = false;

		if (point.x >= getMinX() && point.x <= getMaxX()
			&& point.y >= getMinY() && point.y <= getMaxY())
		{
			bRet = true;
		}

		return bRet;
	}

	bool intersectsRect(const CCRect& rect) const
	{
		return !(     getMaxX() < rect.getMinX() ||
			rect.getMaxX() <      getMinX() ||
			getMaxY() < rect.getMinY() ||
			rect.getMaxY() <      getMinY());
	}
};
//void CGAffineToGL(const CCAffineTransform *t, GLfloat *m)
//{
//	// | m[0] m[4] m[8]  m[12] |     | m11 m21 m31 m41 |     | a c 0 tx |
//	// | m[1] m[5] m[9]  m[13] |     | m12 m22 m32 m42 |     | b d 0 ty |
//	// | m[2] m[6] m[10] m[14] | <=> | m13 m23 m33 m43 | <=> | 0 0 1  0 |
//	// | m[3] m[7] m[11] m[15] |     | m14 m24 m34 m44 |     | 0 0 0  1 |
//
//	m[2] = m[3] = m[6] = m[7] = m[8] = m[9] = m[11] = m[14] = 0.0f;
//	m[10] = m[15] = 1.0f;
//	m[0] = t->a; m[4] = t->c; m[12] = t->tx;
//	m[1] = t->b; m[5] = t->d; m[13] = t->ty;
//}
//
//void GLToCGAffine(const GLfloat *m, CCAffineTransform *t)
//{
//	t->a = m[0]; t->c = m[4]; t->tx = m[12];
//	t->b = m[1]; t->d = m[5]; t->ty = m[13];
//}
void CGAffineToGL2(const CCAffineTransform *t, Matrix4f *m);

CCAffineTransform __CCAffineTransformMake(float a, float b, float c, float d, float tx, float ty);
#define CCAffineTransformMake __CCAffineTransformMake

CCPoint __CCPointApplyAffineTransform(const CCPoint& point, const CCAffineTransform& t);
#define CCPointApplyAffineTransform __CCPointApplyAffineTransform

CCSize __CCSizeApplyAffineTransform(const CCSize& size, const CCAffineTransform& t);
#define CCSizeApplyAffineTransform __CCSizeApplyAffineTransform

CCAffineTransform CCAffineTransformMakeIdentity();
CCRect CCRectApplyAffineTransform(const CCRect& rect, const CCAffineTransform& anAffineTransform);

CCAffineTransform CCAffineTransformTranslate(const CCAffineTransform& t, float tx, float ty);
CCAffineTransform CCAffineTransformRotate(const CCAffineTransform& aTransform, float anAngle);
CCAffineTransform CCAffineTransformScale(const CCAffineTransform& t, float sx, float sy);
CCAffineTransform CCAffineTransformConcat(const CCAffineTransform& t1, const CCAffineTransform& t2);
bool CCAffineTransformEqualToTransform(const CCAffineTransform& t1, const CCAffineTransform& t2);
CCAffineTransform CCAffineTransformInvert(const CCAffineTransform& t);
#endif


